<template>
	<view class="index">
		<view class="index-img" v-if="!showCropper && previewImage">
			<image :src="previewImage" mode="aspectFit" class="preview-image"></image>
		</view>
		<view class="index-img" v-else-if="!showCropper"></view>
		<view class="index-sub" @click="upimages">上传图片</view>

		<!-- 裁剪组件 -->
		<view class="cropper-container" v-if="showCropper">
			<view class="cropper-content">
                <image :src="tempImagePath" class="crop-image" mode="aspectFit" @load="imageLoaded"></image>
				
				<!-- 裁剪框 -->
				<view class="crop-box" 
					:style="{
						left: cropBox.left + 'px',
						top: cropBox.top + 'px',
						width: cropBox.width + 'px',
						height: cropBox.height + 'px'
					}"
					@touchstart="touchStart"
					@touchmove="touchMove"
					@touchend="touchEnd">
					<!-- 四个角的拖动点 -->
                    <view class="corner top-left" @touchstart.stop="cornerTouchStart('topLeft', $event)" @touchmove.stop="cornerTouchMove" @touchend.stop="cornerTouchEnd"></view>
                    <view class="corner top-right" @touchstart.stop="cornerTouchStart('topRight', $event)" @touchmove.stop="cornerTouchMove" @touchend.stop="cornerTouchEnd"></view>
                    <view class="corner bottom-left" @touchstart.stop="cornerTouchStart('bottomLeft', $event)" @touchmove.stop="cornerTouchMove" @touchend.stop="cornerTouchEnd"></view>
                    <view class="corner bottom-right" @touchstart.stop="cornerTouchStart('bottomRight', $event)" @touchmove.stop="cornerTouchMove" @touchend.stop="cornerTouchEnd"></view>
				</view>
			</view>
			
			<!-- 底部按钮 -->
			<view class="cropper-btns">
				<view class="btn cancel" @click="cancelCrop">取消</view>
				<view class="btn confirm" @click="confirmCrop">确定</view>
			</view>
		</view>
		
		<!-- 隐藏的canvas用于裁剪图片 -->
		<canvas canvas-id="cropCanvas" style="position:fixed; left:-1000px; top:-1000px; width:300px; height:300px;"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
            return {
                title: 'Hello',
                showCropper: false,
                tempImagePath: '',
                previewImage: '',
                imageInfo: {
                    width: 0,
                    height: 0
                },
                screen: {
                    width: 0,
                    height: 0
                },
                cropBox: {
                    left: 0,
                    top: 0,
                    width: 200,
                    height: 200
                },
				touch: {
					startX: 0,
					startY: 0,
					moveX: 0,
					moveY: 0
				},
				activeCorner: null,
				cropBoxInitial: {}
			}
		},
		onLoad() {

		},
		methods: {
            upimages() {
                uni.chooseImage({
                    count: 1,
                    success: (chooseImageRes) => {
                        const tempFilePaths = chooseImageRes.tempFilePaths;
                        this.tempImagePath = tempFilePaths[0];
                        this.showCropper = true;
                        
                        // 获取图片信息
                        uni.getImageInfo({
                            src: this.tempImagePath,
                            success: (res) => {
                                this.imageInfo = {
                                    width: res.width,
                                    height: res.height
                                };
                                
                                // 初始化屏幕尺寸与裁剪区域高度（考虑rpx按钮高度）
                                const sys = uni.getSystemInfoSync();
                                const btnH = uni.upx2px(100); // 底部按钮高度：100rpx -> px
                                this.screen.width = sys.windowWidth;
                                this.screen.height = sys.windowHeight - btnH;

                                // 初始化裁剪框位置为居中
                                this.cropBox = {
                                    left: (this.screen.width - 200) / 2,
                                    top: (this.screen.height - 200) / 2,
                                    width: 200,
                                    height: 200
                                };
                            }
                        });
                    }
                });
            },
			
			// 图片加载完成
			imageLoaded() {
				console.log('图片加载完成');
			},
			
			// 裁剪框移动相关方法
			touchStart(e) {
				const touch = e.touches[0];
				this.touch.startX = touch.clientX;
				this.touch.startY = touch.clientY;
				this.cropBoxInitial = { ...this.cropBox };
			},
			
			touchMove(e) {
				const touch = e.touches[0];
				this.touch.moveX = touch.clientX - this.touch.startX;
				this.touch.moveY = touch.clientY - this.touch.startY;
				
				// 更新裁剪框位置
				this.cropBox.left = this.cropBoxInitial.left + this.touch.moveX;
				this.cropBox.top = this.cropBoxInitial.top + this.touch.moveY;
				
				// 边界检查
				this.checkBoundary();
			},
			
			touchEnd() {
				// 重置触摸数据
				this.touch.moveX = 0;
				this.touch.moveY = 0;
			},
			
			// 角落拖动相关方法
            cornerTouchStart(corner, e) {
                this.activeCorner = corner;
                const touch = e.touches[0];
                this.touch.startX = touch.clientX;
                this.touch.startY = touch.clientY;
                this.cropBoxInitial = { ...this.cropBox };
            },
			
			cornerTouchMove(e) {
				if (!this.activeCorner) return;
				
				const touch = e.touches[0];
				this.touch.moveX = touch.clientX - this.touch.startX;
				this.touch.moveY = touch.clientY - this.touch.startY;
				
				// 根据不同角落调整裁剪框大小
				switch (this.activeCorner) {
					case 'topLeft':
						this.cropBox.left = this.cropBoxInitial.left + this.touch.moveX;
						this.cropBox.top = this.cropBoxInitial.top + this.touch.moveY;
						this.cropBox.width = this.cropBoxInitial.width - this.touch.moveX;
						this.cropBox.height = this.cropBoxInitial.height - this.touch.moveY;
						break;
					case 'topRight':
						this.cropBox.top = this.cropBoxInitial.top + this.touch.moveY;
						this.cropBox.width = this.cropBoxInitial.width + this.touch.moveX;
						this.cropBox.height = this.cropBoxInitial.height - this.touch.moveY;
						break;
					case 'bottomLeft':
						this.cropBox.left = this.cropBoxInitial.left + this.touch.moveX;
						this.cropBox.width = this.cropBoxInitial.width - this.touch.moveX;
						this.cropBox.height = this.cropBoxInitial.height + this.touch.moveY;
						break;
					case 'bottomRight':
						this.cropBox.width = this.cropBoxInitial.width + this.touch.moveX;
						this.cropBox.height = this.cropBoxInitial.height + this.touch.moveY;
						break;
				}
				
				// 确保裁剪框不会太小
				if (this.cropBox.width < 50) this.cropBox.width = 50;
				if (this.cropBox.height < 50) this.cropBox.height = 50;
				
				// 边界检查
				this.checkBoundary();
			},
			
			cornerTouchEnd() {
				this.activeCorner = null;
			},
			
			// 边界检查，确保裁剪框不会超出屏幕
            checkBoundary() {
                const screenWidth = this.screen.width;
                const screenHeight = this.screen.height; // 已减去底部按钮高度
                
                // 左边界
                if (this.cropBox.left < 0) this.cropBox.left = 0;
                // 上边界
                if (this.cropBox.top < 0) this.cropBox.top = 0;
                // 右边界
                if (this.cropBox.left + this.cropBox.width > screenWidth) {
                    if (this.activeCorner) {
                        this.cropBox.width = screenWidth - this.cropBox.left;
                    } else {
                        this.cropBox.left = screenWidth - this.cropBox.width;
                    }
                }
                // 下边界
                if (this.cropBox.top + this.cropBox.height > screenHeight) {
                    if (this.activeCorner) {
                        this.cropBox.height = screenHeight - this.cropBox.top;
                    } else {
                        this.cropBox.top = screenHeight - this.cropBox.height;
                    }
                }
            },

            // 计算实际显示的图片矩形（object-fit: contain）
            getDisplayImageRect() {
                const containerW = this.screen.width;
                const containerH = this.screen.height;
                const naturalW = this.imageInfo.width;
                const naturalH = this.imageInfo.height;
                const naturalRatio = naturalW / naturalH;
                const containerRatio = containerW / containerH;

                let displayW, displayH, displayLeft, displayTop;
                if (containerRatio > naturalRatio) {
                    // 受限于高度，图片高度占满，宽度按比例
                    displayH = containerH;
                    displayW = containerH * naturalRatio;
                } else {
                    // 受限于宽度，图片宽度占满，高度按比例
                    displayW = containerW;
                    displayH = containerW / naturalRatio;
                }
                displayLeft = (containerW - displayW) / 2;
                displayTop = (containerH - displayH) / 2;

                return {
                    left: displayLeft,
                    top: displayTop,
                    width: displayW,
                    height: displayH
                };
            },
			
			// 取消裁剪
			cancelCrop() {
				this.showCropper = false;
				this.tempImagePath = '';
			},
			
			// 确认裁剪
            confirmCrop() {
                // 创建canvas进行裁剪
                const ctx = uni.createCanvasContext('cropCanvas', this);
                
                // 设置canvas尺寸与裁剪框一致
                const canvasWidth = this.cropBox.width;
                const canvasHeight = this.cropBox.height;
                
                // 计算显示区域与比例（修正偏移问题）
                const display = this.getDisplayImageRect();
                const scaleX = this.imageInfo.width / display.width;
                const scaleY = this.imageInfo.height / display.height;

                // 将裁剪框从屏幕坐标映射到图片原始坐标
                const relX = this.cropBox.left - display.left;
                const relY = this.cropBox.top - display.top;
                
                // 确保坐标不为负（如果裁剪框超出图片显示区域）
                let x = Math.max(0, relX) * scaleX;
                let y = Math.max(0, relY) * scaleY;
                
                // 计算实际可裁剪的宽高（考虑边界）
                let cropWidth = Math.min(
                    this.cropBox.width * scaleX,
                    this.imageInfo.width - x
                );
                let cropHeight = Math.min(
                    this.cropBox.height * scaleY,
                    this.imageInfo.height - y
                );

                // 在canvas上绘制裁剪后的图片
                ctx.drawImage(this.tempImagePath, x, y, cropWidth, cropHeight, 0, 0, canvasWidth, canvasHeight);
                ctx.draw(false, () => {
                    // 导出图片（指定输出尺寸，避免缩放导致的模糊/偏移）
                    uni.canvasToTempFilePath({
                        canvasId: 'cropCanvas',
                        destWidth: Math.floor(canvasWidth),
                        destHeight: Math.floor(canvasHeight),
                        success: (res) => {
                            this.previewImage = res.tempFilePath;
                            this.showCropper = false;

                            // 上传裁剪后的图片
                            this.uploadCroppedImage(res.tempFilePath);
                        },
                        fail: (err) => {
                            console.error('导出裁剪图片失败', err);
                            uni.showToast({
                                title: '裁剪失败',
                                icon: 'none'
                            });
                        }
                    }, this);
                });
            },
			
			// 上传裁剪后的图片
			uploadCroppedImage(filePath) {
				uni.uploadFile({
					url: 'https://xiaobu.hnjjwl.cn/api/common/upload',
					filePath: filePath,
					name: 'file',
					formData: {
						token: uni.getStorageSync('token')
					},
					success: (res) => {
						let Ima = JSON.parse(res.data);
						console.log(Ima, '上传的裁剪图片');
						uni.showToast({
							title: '裁剪并上传成功',
							icon: 'success'
						});
					},
					fail: (err) => {
						console.error('上传失败', err);
						uni.showToast({
							title: '上传失败',
							icon: 'none'
						});
					}
				});
			}
		}
	}
</script>

<style lang="scss">
	.index {
		width: 100vw;
		height: 100vh;
		float: left;
		background-color: #FFFFFF;

		.index-img {
			width: 690rpx;
			height: 690rpx;
			text-align: center;
			line-height: 690rpx;
			border: 3rpx dashed #999999;
			margin: 20rpx auto 0;
			position: relative;
			
			.preview-image {
				width: 100%;
				height: 100%;
				object-fit: contain;
			}
		}

		.index-sub {
			width: 690rpx;
			height: 85rpx;
			text-align: center;
			line-height: 85rpx;
			border-radius: 10rpx;
			color: #FFF;
			background-color: rgba(42, 121, 255, 1);
			margin: 20rpx auto 0;
		}
		
		.cropper-container {
			position: fixed;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
			background-color: #000;
			z-index: 999;
			display: flex;
			flex-direction: column;
			
			.cropper-content {
				flex: 1;
				position: relative;
				overflow: hidden;
				
                .crop-image {
                    width: 100%;
                    height: 100%;
                }
				
				.crop-box {
					position: absolute;
					border: 2px solid #fff;
					box-sizing: border-box;
					
					.corner {
						position: absolute;
						width: 20px;
						height: 20px;
						border: 2px solid #fff;
						background-color: rgba(0, 0, 0, 0.5);
					}
					
					.top-left {
						top: -10px;
						left: -10px;
						border-right: none;
						border-bottom: none;
					}
					
					.top-right {
						top: -10px;
						right: -10px;
						border-left: none;
						border-bottom: none;
					}
					
					.bottom-left {
						bottom: -10px;
						left: -10px;
						border-right: none;
						border-top: none;
					}
					
					.bottom-right {
						bottom: -10px;
						right: -10px;
						border-left: none;
						border-top: none;
					}
				}
			}
			
			.cropper-btns {
				height: 100rpx;
				display: flex;
				justify-content: space-between;
				align-items: center;
				padding: 0 30rpx;
				background-color: #000;
				
				.btn {
					width: 300rpx;
					height: 80rpx;
					line-height: 80rpx;
					text-align: center;
					border-radius: 10rpx;
					color: #fff;
				}
				
				.cancel {
					background-color: #666;
				}
				
				.confirm {
					background-color: rgba(42, 121, 255, 1);
				}
			}
		}
	}
</style>